package de.tum.in.eist.im.client;


import java.util.Date;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.dom.client.KeyPressEvent;
import com.google.gwt.event.dom.client.KeyPressHandler;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.DialogBox;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.PasswordTextBox;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;

import de.tum.in.eist.im.client.domain.User;

/**
 * Entry point classes define <code>onModuleLoad()</code>.
 */
public class EIST_IM_LOGIN implements EntryPoint {

	static VerticalPanel loginPanel = new VerticalPanel();
	private Label title = new Label("EIST - Instant Messaging since 2011 a.d.");
	private Label logintitle = new Label("Login");
	private Grid loginGrid = new Grid(3, 2);
	private TextBox UsernameTextBox = new TextBox();
	private PasswordTextBox PasswordTextBox = new PasswordTextBox();
	private HorizontalPanel buttonPanel = new HorizontalPanel();
	private Button RegisterButton = new Button("Register");
	private Button LoginButton = new Button("Login");
	private Label UsernameLabel = new Label("Username:");
	private Label PasswordLabel = new Label("Password:");
	protected User loggedInUser; // users who login

	// a box which have a label for text and a Close button
	protected DialogBox infoCloseBox = new DialogBox();
	protected VerticalPanel infoCloseBoxPanel = new VerticalPanel();
	protected Button infoCloseBoxButton = new Button();
	protected Label infoCloseBoxLabel = new Label("");

	protected static ChatServiceAsync proxy = GWT.create(ChatService.class);
	

	public void onModuleLoad() {

		// infoCloseBox initialize
		infoCloseBoxPanel
				.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER);
		infoCloseBox.add(infoCloseBoxPanel);
		infoCloseBoxPanel.add(infoCloseBoxLabel);
		infoCloseBoxPanel.add(infoCloseBoxButton);
		infoCloseBoxButton.setText("Close");
		infoCloseBox.setAnimationEnabled(true);
		infoCloseBox.setGlassEnabled(true);
		// TODO perhaps you can improve the style .... and it is not really
		// center
		// infoCloseBox.setHeight("80px");
		// infoCloseBox.setPopupPosition(120, 120);
		// infoCloseBox.setSize("120px", "120px");
		
		infoCloseBoxButton.addClickHandler(new ClickHandler() {

			@Override
			public void onClick(ClickEvent event) {
				infoCloseBox.hide();

			}
		});

		
		// Associate the Main panel with the HTML host page.
		RootPanel.get("chat").add(loginPanel);
		
		// Login Grid!
		loginPanel.setStyleName("loginPanel");
		loginPanel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER);

		/*
		 * TODO: GET TITLE DESIGNED LIKE AN HEADLINE_1 IN CSS AND LOGINTITLE A
		 * LITTLE SMALLER MIDDLE- AND CENTER-ALIGN THE WHOLE LOGIN MENU E.G.
		 * CHATPANEL! FOR LOOK AND FEEL SEE THE CSS FILE ASSOCIATED WITH THE
		 * setStyleName COMMAND!
		 */

		loginPanel.add(title);
		title.setStyleName("title");
		loginPanel.add(logintitle);
		logintitle.setStyleName("logintitle");

		loginGrid.setStyleName("loginGrid");
		loginPanel.add(loginGrid);

		// TODO: FIX USERNAMELABEL AND PASSWORDLABELS ALIGN, BOTH SHOULD BE
		// MIDDLE ALIGNED OR EVEN LEFT
		// I don't see here a problem ... the align is left, they are OK?

		loginGrid.setWidget(0, 0, UsernameLabel);
		loginGrid.setWidget(0, 1, UsernameTextBox);
		loginGrid.setWidget(1, 0, PasswordLabel);
		loginGrid.setWidget(1, 1, PasswordTextBox);
		loginGrid.setWidget(2, 1, buttonPanel);

		buttonPanel.add(RegisterButton);
		buttonPanel.add(LoginButton);

		buttonPanel.setCellHorizontalAlignment(RegisterButton,
				HasHorizontalAlignment.ALIGN_LEFT);
		buttonPanel.setCellHorizontalAlignment(LoginButton,
				HasHorizontalAlignment.ALIGN_RIGHT);
		
		// Do some GUI tuning
		loginPanel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER); // default-align
		LoginButton.setWidth("70px");
		buttonPanel.setWidth("100%");
		RegisterButton.setWidth("70px");

		// OnClickHandler for the LoginButton
		LoginButton.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				loginUser();
				

			}
		});

		/**
		 * ClickHandler for the Register button
		 */
		RegisterButton.addClickHandler(new ClickHandler() {

			public void onClick(ClickEvent event) {
				registerUser();

			}
		});

		   PasswordTextBox.addKeyPressHandler(new KeyPressHandler() {
			      public void onKeyPress(KeyPressEvent event) {
			        if (event.getCharCode() == KeyCodes.KEY_ENTER && UsernameTextBox.getText().toString() != null && PasswordTextBox.getText().toString() != null) {
			        	loginUser();
			        	UsernameTextBox.setText("");
			        	PasswordTextBox.setText("");
			        }
			      }
			    });
		// only to see the list of registered Users:
		//TODO: _CUT_    RootPanel.get().add(list);

	} // onModuleLoad()

	/**
	 * enables or deactivates all Widgets of the Login screen, so the user could
	 * not change anything
	 * 
	 * @param bo
	 */
/* TODO: See if we still need it!!!
 * 
 		private void enableLoginWidgets(boolean bo) {
		RegisterButton.setEnabled(bo);
		LoginButton.setEnabled(bo);
		UsernameTextBox.setEnabled(bo);
		PasswordTextBox.setEnabled(bo);
	}
	*/



	/**
	 * Method which change some attributes
	 * 
	 * @param info
	 * @param enableCloseButtonGc3Pd8UB7pk3
	 */
	protected void useInfoCloseBox(String info, boolean enableCloseButton) {
		infoCloseBoxLabel.setText(info);
		infoCloseBoxButton.setEnabled(enableCloseButton);
	}
	/**
	 * Method which sets the attributes for the DialogBox and show it in the
	 * center
	 * 
	 * @param title
	 * @param info
	 * @param enableCloseButton
	 */
	protected void useInfoCloseBox(String title, String info,
			boolean enableCloseButton) {
		infoCloseBox.setText(title);
		infoCloseBoxLabel.setText(info);
		infoCloseBoxButton.setEnabled(enableCloseButton);
		infoCloseBox.center();
	}

	/**
	 * Login the User.
	 */
	private void loginUser() {

		// copy from the text boxes into variables
		String loginName = UsernameTextBox.getText().toString();
		String loginPwd = PasswordTextBox.getText().toString();

		loggedInUser = new User(loginName, loginPwd);
		
		  proxy.login(loggedInUser, new
		 AsyncCallback<Boolean>() {
		 
		 @Override public void onFailure(Throwable caught) {
		 useInfoCloseBox("Login User", "Something went wrong ...", true);
		 
		 }
		 
		 @Override public void onSuccess(Boolean result) { 
			 
			 if (result) { // if true ok and go to chat
				 new EIST_IM_CHAT();
			 } else {
				 useInfoCloseBox("Login User",
						 "User is not registered or authentification failed. Please try again."
						 , true); 
			 }
		 
		 } 
		 
		 });
		 
	}

	/**
	 * Registers a new user
	 */
	private void registerUser() {

		String registerName = UsernameTextBox.getText().toString();
		String registerPwd = PasswordTextBox.getText().toString();

		useInfoCloseBox("Register User", "Register User. Please wait ...",
				false);

		
		 proxy.registerNewUser(new User(registerName,registerPwd), new
		 AsyncCallback<Void>() {
		  
		  @Override public void onSuccess(Void result) {
		  useInfoCloseBox("Register User successfull", true);
		  
		  }
		  
		  @Override public void onFailure(Throwable caught) {
		  useInfoCloseBox("Register User failed", true);
		  
		  } });
	}
	
	/**
	 * Logouts the user from the server. Could show an error
	 * with a DialogBox (than the method does nothing)
	 * @param widget Widget which must be remove from RootPanel.get("chat") 
	 */
	protected void logoutUser(final Widget widget) {
		
		useInfoCloseBox("Log out", "please wait ...", false);
		
		proxy.logout(loggedInUser, new AsyncCallback<Boolean>() {
			
			@Override
			public void onSuccess(Boolean result) {
				if (result) {
					RootPanel.get("chat").remove(widget);
					RootPanel.get("chat").add(loginPanel);
					
					infoCloseBox.hide();
				} else
					useInfoCloseBox("something went wrong please try again!",
							true);
				
			}
			
			@Override
			public void onFailure(Throwable caught) {
				useInfoCloseBox("something went wrong please try again!",
						true);
			}
		});
	}
	
	/*
	 * show a box for registering a user
	 */
	private void registerUserBox() {
		DialogBox diag = new DialogBox();
		
	}
}
		 

		//TODO: _CUT_  This code should not work, because this list is only on the client
		// side
		// if(findUser(registerUser)==null){
		// list.add(nameLabel);
		//
		// nameLabel.setText(registername);
		// Window.alert("User erfolgreich registriert!");
		//
		// }
		// else if (findUser(registerUser)== registerUser){
		// Window.alert("Der User kann nicht registriert werden, er existiert bereits!");
		// }

	 // registerUser()

	/**
	 * TODO comment
	 * 
	 * @param registerUser
	 * @return
	 */
	
	/*
	 private User findUser(User registerUser) { for(Iterator<Widget> i =
	 list.iterator(); i.hasNext()==true;){
	 
	 Label a = (Label) i.next();
	 
	 if(registerUser.getUsername().equals(a.getText().toString())){ return
	 registerUser; }
	 
	 if(i.hasNext()==false){ return null; }
	 
	 } return null; }
	*/
	
